home *** CD-ROM | disk | FTP | other *** search
/ Java 1996 August / Java - Summer 1996.iso / kaffe-0.2 / kaffe2native / kaffe2native.c next >
C/C++ Source or Header  |  1996-02-12  |  10KB  |  585 lines

  1. /*
  2.  * kaffe2native.c
  3.  * This program reads in a kaffe.def file and converts it to the necessary
  4.  * source files for the kaffe machine.
  5.  *
  6.  * Copyright (c) 1996 Systems Architecture Research Centre,
  7.  *           City University, London, UK.
  8.  *
  9.  * See the file "license.terms" for information on usage and redistribution
  10.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  *
  12.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
  13.  */
  14.  
  15. #include <stdio.h>
  16.  
  17. void openFiles(void);
  18. void process(void);
  19. void processInstruction(void);
  20. void processRegister(void);
  21. void processOpcodes(void);
  22. void getLine(void);
  23. void skipSpace(void);
  24. void finish(void);
  25.  
  26. #define    SHEADER \
  27. "/*\n\
  28.  * instn.c\n\
  29.  * Real instruction and register information.\n\
  30.  */\n\
  31. \n\
  32. #include \"instruction.h\"\n\
  33. #include \"register.h\"\n\
  34. #include \"gen.h\"\n\
  35. \n\
  36. /*\n\
  37.  * Declare the translation between Kaffe VM instructions and native instructions.\n\
  38.  */\n\
  39. nativeInstn instnTable[256] = {\n\
  40. \n\
  41. /* in, out, size, emulate, code */\n"
  42.  
  43. #define    GHEADER \
  44. "/*\n\
  45.  * gen.c\n\
  46.  * Generated instruction sequences.\n\
  47.  */\n\
  48. \n\
  49. #include <assert.h>\n\
  50. #include \"instruction.h\"\n\
  51. #include \"soft.h\"\n\
  52. #include \"asm.h\"\n\
  53. \n\
  54. void gen_UNKNOWN(instn* i)\n\
  55. {\n\
  56. }\n\
  57. \n"
  58.  
  59. #define    GHEADERH \
  60. "/*\n\
  61.  * gen.h\n\
  62.  * Generated instruction sequences.\n\
  63.  */\n\
  64. \n\
  65. typedef void (*genfunc)(instn*);\n\
  66. \n\
  67. void gen_UNKNOWN(instn*);\n\
  68. "
  69.  
  70. #define    BHEADERH \
  71. "/*\n\
  72.  * bytecode.h\n\
  73.  * Generate bytecode defines.\n\
  74.  */\n\
  75. \n\
  76. #ifndef __bytecode_h\n\
  77. #define __bytecode_h\n\
  78. \n\
  79. typedef unsigned char bytecode;\n\
  80. \n"
  81.  
  82. #define    MAXREG    64
  83. #define    MAXOP    256
  84.  
  85. #define    MAXBUF    200
  86.  
  87. #define    SOUT    "instn.c"
  88. #define    GOUT    "gen.c"
  89. #define    GOUTH    "gen.h"
  90. #define    BOUTH    "bytecode.h"
  91.  
  92. FILE* in;
  93. FILE* sout;
  94. FILE* gout;
  95. FILE* gouth;
  96. FILE* bouth;
  97.  
  98. int line;
  99. char* buf;
  100. int regno;
  101.  
  102. char opcode[MAXOP][MAXBUF];
  103. char regs[MAXREG][MAXBUF];
  104.  
  105. main(int c, char* argv[])
  106. {
  107.     char* input = "kaffe.def";
  108.     if (c == 2) {
  109.         input = argv[1];
  110.     }
  111.     in = fopen(input, "r");
  112.     if (in == 0) {
  113.         fprintf(stderr, "Cannot find %s\n", input);
  114.         exit(1);
  115.     }
  116.     openFiles();
  117.     fputs(SHEADER, sout);
  118.     fputs(GHEADER, gout);
  119.     fputs(GHEADERH, gouth);
  120.     fputs(BHEADERH, bouth);
  121.     process();
  122.     finish();
  123.     exit(0);
  124. }
  125.  
  126. void
  127. openFiles(void)
  128. {
  129.     sout = fopen(SOUT, "w");
  130.     if (sout == 0) {
  131.         fprintf(stderr, "Cannot create %s\n", SOUT);
  132.         exit(1);
  133.     }
  134.     gout = fopen(GOUT, "w");
  135.     if (gout == 0) {
  136.         fprintf(stderr, "Cannot create %s\n", GOUT);
  137.         exit(1);
  138.     }
  139.     gouth = fopen(GOUTH, "w");
  140.     if (gouth == 0) {
  141.         fprintf(stderr, "Cannot create %s\n", GOUTH);
  142.         exit(1);
  143.     }
  144.     bouth = fopen(BOUTH, "w");
  145.     if (bouth == 0) {
  146.         fprintf(stderr, "Cannot create %s\n", BOUTH);
  147.         exit(1);
  148.     }
  149. }
  150.  
  151. void
  152. process(void)
  153. {
  154.     while (getLine(), buf != 0) {
  155.         if (buf[0] == '#' || isspace(buf[0])) {
  156.             continue;
  157.         }
  158.         else if (strncmp(buf, "insn", 4) == 0) {
  159.             processInstruction();
  160.         }
  161.         else if (strncmp(buf, "reg", 3) == 0) {
  162.             processRegister();
  163.         }
  164.         else {
  165.             fprintf(stderr, "Bad data at line %d\n", line);
  166.             exit(1);
  167.         }
  168.     }
  169. }
  170.  
  171. /*
  172.  * eg. insn FADD(in=float,float; out=float; sync) = 98
  173.  */
  174. void
  175. processInstruction(void)
  176. {
  177.     char* name;
  178.     char* type;
  179.     int ins;
  180.     int outs;
  181.     int op;
  182.     int soft;
  183.  
  184.     type = "i_hard";
  185.  
  186.     buf += 4;
  187.     skipSpace();
  188.  
  189.     name = buf;
  190.     for (; *buf != 0; buf++) {
  191.         if (*buf == '(' || isspace(*buf)) {
  192.             *buf = 0;
  193.             buf++;
  194.             goto inout;
  195.         }
  196.     }
  197.     fprintf(stderr, "Bad instruction format at line %d\n", line);
  198.     exit(1);
  199.  
  200.     inout:
  201.     for(;;) {
  202.         skipSpace();
  203.         if (buf[0] == ')') {
  204.             buf++;
  205.             break;
  206.         }
  207.  
  208.         if (strncmp(buf, "in=", 3) == 0) {
  209.             buf += 3;
  210.             ins = countTypes();
  211.         }
  212.         else if (strncmp(buf, "out=", 4) == 0) {
  213.             buf += 4;
  214.             outs = countTypes();
  215.         }
  216.         else if (strncmp(buf, "sync", 4) == 0) {
  217.             buf += 4;
  218.             type = "i_sync";
  219.             soft = 1;
  220.         }
  221.         else if (strncmp(buf, "soft", 4) == 0) {
  222.             buf += 4;
  223.             type = "i_soft";
  224.             soft = 1;
  225.         }
  226.         else if (strncmp(buf, "hard", 4) == 0) {
  227.             buf += 4;
  228.             type = "i_hard";
  229.             soft = 0;
  230.         }
  231.     }
  232.  
  233.     skipSpace();
  234.     if (buf[0] == '=') {
  235.         buf++;
  236.     }
  237.     skipSpace();
  238.     op = atoi(buf);
  239.     if (op >= MAXOP) {
  240.         fprintf(stderr, "Opcode too big at line %d\n", line);
  241.         exit(1);
  242.     }
  243.  
  244.     /* Supress ins and outs for sync and soft instructions */
  245.     if (soft == 1) {
  246.         ins = 0;
  247.         outs = 0;
  248.     }
  249.  
  250.     sprintf(opcode[op], " { %d, %d, %d, %s, gen_%s },\n",
  251.         ins, outs, 0, type, name);
  252.  
  253.     getLine();
  254.     if (buf[0] != '{') {
  255.         fprintf(stderr, "No code body at line %d\n", line);
  256.         exit(1);
  257.     }
  258.  
  259.     fprintf(gouth, "void gen_%s(instn*);\n", name);
  260.     fprintf(gout, "void gen_%s(instn* i)\n{\n", name);
  261.     fprintf(bouth, "#define %s %d\n", name, op);
  262.     for (;;) {
  263.         getLine();
  264.         if (buf[0] == '}') {
  265.             break;
  266.         }
  267.         processOpcodes();
  268.     }
  269.     fprintf(gout, "}\n\n");
  270. }
  271.  
  272. void
  273. processOpcodes(void)
  274. {
  275.     int i;
  276.     int j;
  277.     int a;
  278.     char obuf[MAXBUF];
  279.     char abuf[MAXBUF];
  280.     int r;
  281.  
  282.     /* First handle literal escapes */
  283.     if (buf[0] == '+') {
  284.         buf++;
  285.         skipSpace();
  286.         fprintf(gout, "\t%s", buf);
  287.         return;
  288.     }
  289.  
  290.     skipSpace();
  291.  
  292.     /* Process opcode to something we can use as a function name */
  293.     j = 0;
  294.     i = 0;
  295.     a = 0;
  296.     abuf[0] = 0;
  297.     while (buf[i] != 0) {
  298.         switch (buf[i++]) {
  299.         /* Input register */
  300.         case 'I':
  301.         case 'W':
  302.         case 'B':
  303.             r = buf[i++] - '1';
  304.             sprintf(&abuf[a], "i->in[%d].reg->regno,", r);
  305.             obuf[j++] = 'R';
  306.             break;
  307.  
  308.         /* Output register */
  309.         case 'O':
  310.             r = buf[i++] - '1';
  311.             sprintf(&abuf[a], "i->out[%d].reg->regno,", r);
  312.             obuf[j++] = 'R';
  313.             break;
  314.  
  315.         /* Local constant */
  316.         case 'C':
  317.         /* Integer value */
  318.         case 'V':
  319.             r = buf[i++] - '1';
  320.             sprintf(&abuf[a], "i->value[%d],", r);
  321.             obuf[j++] = 'V';
  322.             break;
  323.  
  324.         /* Local variable */
  325.         case 'L':
  326.             r = buf[i++] - '1';
  327.             sprintf(&abuf[a], "4*(i->value[%d]),REG_BASE,", r);
  328.             obuf[j++] = 'V';
  329.             obuf[j++] = 'o';
  330.             obuf[j++] = 'R';
  331.             obuf[j++] = 'o';
  332.             break;
  333.  
  334.         /* Stack value */
  335.         case 'S':
  336.             r = buf[i++] - '1';
  337.             sprintf(&abuf[a], "4*%d,REG_STACK,", r);
  338.             obuf[j++] = 'V';
  339.             obuf[j++] = 'o';
  340.             obuf[j++] = 'R';
  341.             obuf[j++] = 'o';
  342.             break;
  343.  
  344.         /* Jump address */
  345.         case 'J':
  346.             sprintf(&abuf[a], "i->value[0],");
  347.             obuf[j++] = 'J';
  348.             break;
  349.  
  350.         /* Jump to absolute address */
  351.         case 'X':
  352.             sprintf(&abuf[a], "i->value[0],");
  353.             obuf[j++] = 'X';
  354.             break;
  355.  
  356.         case ',':
  357.             obuf[j++] = 'x';
  358.             break;
  359.  
  360.         case '(':
  361.         case ')':
  362.             obuf[j++] = 'o';
  363.             break;
  364.  
  365.         case ' ':
  366.         case '\t':
  367.             obuf[j++] = '_';
  368.             break;
  369.  
  370.         case '$':
  371.         case '\n':
  372.             break;
  373.  
  374.         case '*':
  375.             obuf[j++] = 's';
  376.             break;
  377.  
  378.         case '0': case '1': case '2': case '3': case '4':
  379.         case '5': case '6': case '7': case '8': case '9':
  380.         case '-':
  381.             i--;
  382.             while (isxdigit(buf[i]) || 
  383.               buf[i] == '-' || buf[i] == 'x') {
  384.                 abuf[a] = buf[i];
  385.                 i++;
  386.                 a++;
  387.             }
  388.             sprintf(&abuf[a], ",");
  389.             obuf[j++] = 'V';
  390.             break;
  391.  
  392.         /* Specific register name */
  393.         case '%':
  394.             sprintf(&abuf[a], "REG_");
  395.             a += 4;
  396.             while (isalnum(buf[i])) {
  397.                 abuf[a] = buf[i];
  398.                 i++;
  399.                 a++;
  400.             }
  401.             sprintf(&abuf[a], ",");
  402.             obuf[j++] = 'R';
  403.             break;
  404.  
  405.         /* Soft routine calls */
  406.         case '_':
  407.             if (strncmp(&buf[i], "soft", 4) != 0) {
  408.                 obuf[j++] = buf[i-1];
  409.             }
  410.             else {
  411.                 sprintf(&abuf[a], "(int)");
  412.                 a += 5;
  413.                 while (isalnum(buf[i]) ||
  414.                   buf[i] == '_') {
  415.                     abuf[a] = buf[i];
  416.                     i++;
  417.                     a++;
  418.                 }
  419.                 sprintf(&abuf[a], ",");
  420.                 obuf[j++] = 'X';
  421.             }
  422.             break;
  423.  
  424.         default:
  425.             obuf[j++] = buf[i-1];
  426.             while (isalnum(buf[i])) {
  427.                 obuf[j++] = buf[i++];
  428.             }
  429.             break;
  430.         }
  431.         a = strlen(abuf);
  432.     }
  433.     obuf[j] = 0;
  434.     for (j--; obuf[j] == '_'; j--) {
  435.         obuf[j] = 0;
  436.     }
  437.     if (a > 0 && abuf[a-1] == ',') {
  438.         abuf[a-1] = 0;
  439.     }
  440.  
  441.     fprintf(gout, "\tasm__%s(%s);\n", obuf, abuf);
  442. }
  443.  
  444. /*
  445.  * eg. reg %eax int = 0
  446.  */
  447. void
  448. processRegister(void)
  449. {
  450.     char* name;
  451.     char* type;
  452.     char* nr;
  453.  
  454.     buf += 3;
  455.     skipSpace();
  456.     name = buf;
  457.     for (; *buf != 0; buf++) {
  458.         if (*buf == ',' || isspace(*buf)) {
  459.             *buf = 0;
  460.             buf++;
  461.             goto wn;
  462.         }
  463.     }
  464.     fprintf(stderr, "Bad register format at line %d\n", line);
  465.     exit(1);
  466.  
  467.     wn:
  468.     /* Skip type definition */
  469.     skipSpace();
  470.     type = buf;
  471.     for (; *buf != 0; buf++) {
  472.         if (*buf == ',' || isspace(*buf)) {
  473.             *buf = 0;
  474.             buf++;
  475.             goto nn;
  476.         }
  477.     }
  478.     fprintf(stderr, "Bad register format at line %d\n", line);
  479.     exit(1);
  480.  
  481.     nn:
  482.     skipSpace();
  483.     buf++; /* Skip = */
  484.     skipSpace();
  485.     nr = buf;
  486.  
  487.     if (regno >= MAXREG) {
  488.         fprintf(stderr, "Register number too big at line %d\n", line);
  489.         exit(1);
  490.     }
  491.     sprintf(regs[regno], " { \"%s\", %d, MAXSTACK, 0 },\n",
  492.         name, atoi(nr));
  493.     regno++;
  494. }
  495.  
  496. void
  497. finish(void)
  498. {
  499.     int i;
  500.  
  501.     /* Generate instruction table */
  502.     for (i = 0; i < 256; i++) {
  503.         if (opcode[i][0] != 0) {
  504.             fputs(opcode[i], sout);
  505.         }
  506.         else {
  507.             fputs(" { 0, 0, 0, i_soft, gen_UNKNOWN },\n", sout);
  508.         }
  509.     }
  510.     fputs("\n};\n", sout);
  511.  
  512.     fputs("\nnativeReg registerFile[] = {\n", sout);
  513.     for (i = 0; i < regno; i++) {
  514.         fputs(regs[i], sout);
  515.     }
  516.     fputs("};\n", sout);
  517.  
  518.     fprintf(bouth, "\n#endif\n");
  519. }
  520.  
  521. int
  522. countTypes(void)
  523. {
  524.     int count = 0;
  525.  
  526.     for (;;) {
  527.         skipSpace();
  528.         if (buf[0] == ',') {
  529.             buf++;
  530.         }
  531.         else if (buf[0] == ')') {
  532.             return (count);
  533.         }
  534.         else if (buf[0] == ';') {
  535.             buf++;
  536.             return (count);
  537.         }
  538.         skipSpace();
  539.         if (strncmp(buf, "none", 4) == 0) {
  540.             buf += 4;
  541.             count = 0;
  542.         }
  543.         else if (strncmp(buf, "any", 3) == 0) {
  544.             buf += 3;
  545.             count += 1;
  546.         }
  547.         else if (strncmp(buf, "int", 3) == 0) {
  548.             buf += 3;
  549.             count += 1;
  550.         }
  551.         else if (strncmp(buf, "long", 4) == 0) {
  552.             buf += 4;
  553.             count += 2;
  554.         }
  555.         else if (strncmp(buf, "float", 5) == 0) {
  556.             buf += 5;
  557.             count += 1;
  558.         }
  559.         else if (strncmp(buf, "double", 6) == 0) {
  560.             buf += 6;
  561.             count += 2;
  562.         }
  563.         else if (strncmp(buf, "objref", 6) == 0) {
  564.             buf += 6;
  565.             count += 1;
  566.         }
  567.     }
  568. }
  569.  
  570. void
  571. getLine(void)
  572. {
  573.     static char lbuf[MAXBUF];
  574.     line++;
  575.     buf = fgets(lbuf, sizeof(lbuf), in);
  576. }
  577.  
  578. void
  579. skipSpace(void)
  580. {
  581.     while (isspace(*buf)) {
  582.         buf++;
  583.     }
  584. }
  585.